package com.hopes.bizz.poll.statistic.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hopes.bizz.common.core.util.CollectionUtils;
import com.hopes.bizz.common.core.util.StringUtils;
import com.hopes.bizz.poll.common.constant.MonitorConstant;
import com.hopes.bizz.poll.common.constant.enums.PollModDictEnum;
import com.hopes.bizz.poll.factor.entity.PollDisplayFactorEntity;
import com.hopes.bizz.poll.factor.entity.PollFactorInfoEntity;
import com.hopes.bizz.poll.factor.service.PollDisplayFactorService;
import com.hopes.bizz.poll.factor.service.PollFactorInfoService;
import com.hopes.bizz.poll.gis.bo.GISMonitorSite;
import com.hopes.bizz.poll.gis.bo.GISSiteNum;
import com.hopes.bizz.poll.gis.vo.GISDisplayFactor;
import com.hopes.bizz.poll.gis.vo.GISInfo;
import com.hopes.bizz.poll.gis.vo.GISSiteOverview;
import com.hopes.bizz.poll.information.service.PollTownService;
import com.hopes.bizz.poll.monitor.entity.PollMonitorSiteEntity;
import com.hopes.bizz.poll.monitor.service.PollMonitorSiteService;
import com.hopes.bizz.poll.monitor.service.PollMonitorTypeService;
import com.hopes.bizz.poll.statistic.service.GISService;
import com.hopes.boss.admin.api.feign.RemoteCompanyService;
import com.hopes.boss.admin.api.resolver.DictResolver;
import com.hopes.boss.common.core.constant.SecurityConstants;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author daijie
 * @version 1.0
 * @date 2023/6/6 15:21
 * @Description:
 */
@Service
public class GISServiceImpl implements GISService {

    @Autowired
    private PollMonitorSiteService pollMonitorSiteService;
    @Autowired
    private PollMonitorTypeService pollMonitorTypeService;
    @Autowired
    private PollTownService pollTownService;
    @Autowired
    private RemoteCompanyService remoteCompanyService;
    @Autowired
    private PollDisplayFactorService pollDisplayFactorService;
    @Autowired
    private PollFactorInfoService pollFactorInfoService;

    @Override
    public GISInfo getGISInfo() {
        GISInfo gisInfo = new GISInfo();
        List<GISMonitorSite> gisMonitorSiteList= new ArrayList<>();

        LambdaQueryWrapper<PollMonitorSiteEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(PollMonitorSiteEntity::getIsUse, true);
        wrapper.orderByDesc(PollMonitorSiteEntity::getMonitorType);
        List<PollMonitorSiteEntity> monitorSites = pollMonitorSiteService.list(wrapper);
        for (PollMonitorSiteEntity monitorSite : monitorSites) {
            GISMonitorSite gisMonitorSite = new GISMonitorSite();

            BeanUtils.copyProperties(monitorSite, gisMonitorSite);
            gisMonitorSite.setMonitorSiteId(monitorSite.getId());
            gisMonitorSiteList.add(gisMonitorSite);
        }

        gisInfo.setGisMonitorSiteList(gisMonitorSiteList);
        return gisInfo;
    }

    @Override
    public GISSiteOverview gisSiteOverviewByMainType(Integer mainType) {
        GISSiteOverview result = new GISSiteOverview();
        List<GISSiteNum> gisSiteNums = new ArrayList<>();

        List<Integer> monitorTypeByMain = pollMonitorTypeService.getMonitorTypeByMain(mainType);
        LambdaQueryWrapper<PollMonitorSiteEntity> monitorWrapper = new LambdaQueryWrapper<>();
        monitorWrapper.in(PollMonitorSiteEntity::getMonitorType, monitorTypeByMain);
        Map<String, Long> collect = pollMonitorSiteService.list(monitorWrapper).stream().collect(Collectors.groupingBy(PollMonitorSiteEntity::getMonitorType, Collectors.counting()));

        for (String type : collect.keySet()) {
            Long num = collect.get(type);

            GISSiteNum siteNum = new GISSiteNum();
            siteNum.setNum(num);
            siteNum.setMonitorType(Integer.valueOf(type));
            siteNum.setName(DictResolver.getItemLabelByValue(PollModDictEnum.site_type, type));
            gisSiteNums.add(siteNum);
        }
        result.setSiteNum(gisSiteNums);

        if (MonitorConstant.MONITOR_TYPE_AIR.equals(mainType)) {
            result.setTownNum(pollTownService.count());
        } else if (MonitorConstant.MONITOR_TYPE_POLL.equals(mainType)) {
            result.setOrgNum(remoteCompanyService.count(SecurityConstants.FROM_IN).getData());
        }

        return result;
    }

    @Override
    public List<GISDisplayFactor> getDisplayFactorByMonitorTypeMain(Integer monitorTypeMain) {
        List<Integer> monitorTypeByMain = pollMonitorTypeService.getMonitorTypeByMain(monitorTypeMain);
        List<GISDisplayFactor> result = new ArrayList<>();

        for (Integer type : monitorTypeByMain) {
            LambdaQueryWrapper<PollDisplayFactorEntity> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(PollDisplayFactorEntity::getMonitorType, type);
            String ids = pollDisplayFactorService.getBaseMapper().selectList(wrapper).stream().map(PollDisplayFactorEntity::getFactorIds).collect(Collectors.joining(","));
            List<String> factorIds;
            LambdaQueryWrapper<PollFactorInfoEntity> pollMonitorFactorWrapper = new LambdaQueryWrapper<>();
            if (StringUtils.isNotEmpty(ids)) {
                // 展示因子id
                factorIds = CollectionUtils.arrayToList(ids.split(","));
                // 查询因子
                pollMonitorFactorWrapper
                        .in(CollectionUtils.isNotEmpty(factorIds), PollFactorInfoEntity::getId, factorIds)
                        .eq(PollFactorInfoEntity::getUseFlag, true)
                        .orderByAsc(PollFactorInfoEntity::getSortNum);
                List<PollFactorInfoEntity> list = pollFactorInfoService.list(pollMonitorFactorWrapper);

                GISDisplayFactor displayFactor = new GISDisplayFactor();
                displayFactor.setType(type);
                displayFactor.setFactors(list.stream().
                        collect(Collectors.collectingAndThen(Collectors.toCollection(() ->
                                new TreeSet<>(Comparator.comparing(PollFactorInfoEntity::getId))), ArrayList::new)));

                result.add(displayFactor);
            }
        }

        return result;
    }
}
